package com.tfd.blog.repository;

import com.tfd.blog.domain.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author TangFD@HF 2019/5/8
 */
@Repository
public interface ArticleRepository extends JpaRepository<Article, String>, JpaSpecificationExecutor<Article> {

    /**
     * 根据状态匹配查询文章
     *
     * @param status   文章状态
     * @param pageable 分页对象
     * @return 包含文章的分页对象
     */
    Page<Article> findByStatusAndCategoryIdInOrderByUpdateDateDesc(String status, List<String> categoryIds, Pageable pageable);

    /**
     * 根据标题，内容，简介 模糊匹配查询文章
     *
     * @param title       标题
     * @param content     内容
     * @param description 简介
     * @param pageable    分页对象
     * @return 包含文章的分页对象
     */
    Page<Article> findByTitleLikeOrContentLikeOrDescriptionLikeOrderByCreateDateDesc(String title,
                                                                                     String content,
                                                                                     String description,
                                                                                     Pageable pageable);

    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @Modifying
    @Query("update Article set likeCount = likeCount + 1 where id = :id")
    void praise(@Param("id") String id);

    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @Modifying
    @Query("update Article set readCount = readCount + 1 where id = :id")
    void read(@Param("id") String id);

    @Query(nativeQuery = true, value = "select id,title from t_blog_article " +
            "where publish_date < :pd order by publish_date desc limit 1")
    Object getPreArticleId(@Param("pd") Date publishDate);

    @Query(nativeQuery = true, value = "select id,title from t_blog_article " +
            "where publish_date > :pd order by publish_date asc limit 1")
    Object getNextArticleId(@Param("pd") Date publishDate);

    @Query("select c.id as id,c.name as name,count(a.id) as num from Category c inner join Article a " +
            "on c.id=a.categoryId where a.status = 'PUBLISH' group by c.id order by num desc ")
    List<Map<String, Object>> categoryCount();
}
